package edu.hit.stu.config;

import edu.hit.stu.filter.JwtFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.DefaultServerRedirectStrategy;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.savedrequest.ServerRequestCache;
import org.springframework.security.web.server.savedrequest.WebSessionServerRequestCache;
import org.springframework.web.server.ServerWebExchange;

import java.net.URI;


/**
 * @author 刘智彬
 */
@EnableWebFluxSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final JwtFilter jwtFilter;
    private final JWTReactiveAuthenticationManager jwtReactiveAuthenticationManager;
    private final JWTSecurityContextRepository jwtSecurityContextRepository;

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http
                .authorizeExchange(exchanges -> exchanges
                        .pathMatchers("/authentication").permitAll()
                        .anyExchange().authenticated()
                )
                .csrf(ServerHttpSecurity.CsrfSpec::disable)
                .addFilterAfter(jwtFilter, SecurityWebFiltersOrder.FIRST)
                .authenticationManager(jwtReactiveAuthenticationManager)
                .securityContextRepository(jwtSecurityContextRepository);
        return http.build();
    }

    private Customizer<ServerHttpSecurity.FormLoginSpec> formLoginSpecCustomizer() {
        return formLoginSpec -> formLoginSpec.authenticationSuccessHandler((webFilterExchange, authentication) -> {
            ServerWebExchange exchange = webFilterExchange.getExchange();
            ServerRequestCache requestCache = new WebSessionServerRequestCache();
            return requestCache.getRedirectUri(exchange)
                    .defaultIfEmpty(URI.create("/login"))
                    .flatMap(location -> new DefaultServerRedirectStrategy().sendRedirect(exchange, location));
        });
    }
}
